// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
const vscode = require('vscode');
const webview = require('./views');
const fs = require('fs');

const TerminalList = new Map();

const messageHandel = {
	creatMkdirAndCmd(data) {
		if (!fs.existsSync(data.path)) {
			var dirs = [];
			var dir = data.path;
			while (!fs.existsSync(dir)) {
				dirs.unshift(dir.slice(dir.lastIndexOf('/')))
				dir = data.path.slice(0, dir.lastIndexOf('/'))
			}
			for (let v of dirs) {
				fs.mkdirSync(dir += `/${v}`)
			}
		}
	},
	start: function (data) {
		let cmd = ""
		if (fs.existsSync(data.path)) {
			cmd = `cd ${data.path}`
		} else {
			var dirs = [];
			var dir = data.path;
			while (!fs.existsSync(dir)) {
				dirs.unshift(dir.slice(dir.lastIndexOf('/')))
				dir = data.path.slice(0, dir.lastIndexOf('/'))
			}
			for (let v of dirs) {
				fs.mkdirSync(dir += `/${v}`)
			}
			cmd = `cd ${data.path.slice(0, data.path.lastIndexOf('/'))} && git clone ${data.git} && cd ${data.path} && npm i`
		}

		const runcommand = data.environment === 'production' ? data.scripts.build : data.scripts.dev;

		const commandStr = `${cmd} && ${runcommand}`;

		if(TerminalList.has(data.id)){
			TerminalList.get(data.id).show()
			TerminalList.get(data.id).sendText(commandStr)
		}else{
			TerminalList.set(data.id, createTerminal({
				commandStr,
				...data
			}))
		}
	},
	stop: function (data) {
		if(!TerminalList.has(data.id)) return;
		TerminalList.get(data.id).dispose();
		TerminalList.delete(data.id)
	},
	openProject: function (data) {
		if(!fs.existsSync(data.path)){
			vscode.window.showErrorMessage(`项目 ${data.name} 不存在！请启动项目，进行仓库代码拉取.`)
			return;
		}
		vscode.commands.executeCommand('micro-view.openProject');
		TerminalList.get('openProjectTerminal').sendText(`cd ${data.path} && code -n .`)
	},
	showTerminal: function (data) {
		if (TerminalList.has(data.id)) {
			TerminalList.get(data.id).show()
		}else{
			TerminalList.set(data.id, createTerminal(data))
			if (fs.existsSync(data.path)) {
				TerminalList.get(data.id).sendText(`cd ${data.path}`)
			}
		}
	}
}

// this method is called when your extension is activated
// your extension is activated the very first time the command is executed

function createTerminal(obj = {}) {
	const { name, commandStr } = Object.assign({
		name: 'node',
		commandStr: ''
	}, obj)

	const ct = vscode.window.createTerminal({ name: name });

	ct.show(true);

	commandStr && ct.sendText(commandStr);

	return ct;

}

function loadFileTexts() {

	const { document, selection } = vscode.window.activeTextEditor;

	return document.getText();

}

function createWebviewPanel() {
	const panel = vscode.window.createWebviewPanel(
		'应用视图', 
		"应用视图",
		vscode.ViewColumn.One,
		{
			enableScripts: true,
			retainContextWhenHidden: true
		}
	);
	panel.webview.html = webview()

	const texts = loadFileTexts()

	//关闭view，清除所有终端
	panel.onDidDispose(() => {
		for (let value of TerminalList.values()) {
			value.dispose();
		}
	})

	//消息通信
	panel.webview.onDidReceiveMessage(message => {
		const { type, data } = message
		
		switch (type) {
			case 'start':
				vscode.window.showInformationMessage(`应用 ${data.name} 即将启动.`)
				messageHandel.start(data)
				break;
			case 'restart':
				vscode.window.showInformationMessage(`应用 ${data.name} 即将重启.`)
				messageHandel.stop(data)
				messageHandel.start(data)
				break;
			case 'stop': 
				vscode.window.showInformationMessage(`应用 ${data.name} 即将退出.`)
				messageHandel.stop(data)
				break;
			case 'openProject':
				messageHandel.openProject(data)
				break;
			case 'showTerminal':
				messageHandel.showTerminal(data)
		}
	});

	setTimeout(() => {
		panel.webview.postMessage(texts);
	}, 1000)
	
}

/**
 * @param {vscode.ExtensionContext} context
 */
function activate(context) {

	// Use the console to output diagnostic information (console.log) and errors (console.error)
	// This line of code will only be executed once when your extension is activated
	console.log('Congratulations, your extension "micro-view" is now active!');

	// The command has been defined in the package.json file
	// Now provide the implementation of the command with  registerCommand
	// The commandId parameter must match the command field in package.json

	context.subscriptions.push(vscode.commands.registerCommand('micro-view.runTerminals', () => {
		createWebviewPanel();
	}));

	context.subscriptions.push(vscode.commands.registerCommand('micro-view.openProject', () => {
		if (!TerminalList.has('openProjectTerminal')) {
			TerminalList.set('openProjectTerminal', createTerminal())
		}
	}));

}

// this method is called when your extension is deactivated
function deactivate() {}

module.exports = {
	activate,
	deactivate
}
